package com.playball.lottery.util;



public class IdCard {
    
    private String idCardNum = null;
    
    private static int IS_EMPTY = 1;
    private static int LEN_ERROR = 2;
    private static int CHAR_ERROR = 3;
    private static int DATE_ERROR = 4;
    private static int CHECK_BIT_ERROR = 5;
    
    private String[] errMsg = new String[] {"身份证完全正确！", 
                                            "身份证为空！", 
                                            "身份证长度不正确！", 
                                            "身份证有非法字符！", 
                                            "身份证中出生日期不合法！", 
                                            "身份证校验位错误！"};
    
    private int error = 0;
    
    /**
     * 构造方法。
     * @param idCardNum
     */
    public IdCard(String idCardNum) {
       // super();
        this.idCardNum = idCardNum.trim();
    }
    
    public String getIdCardNum() {
        return idCardNum;
    }

    public void setIdCardNum(String idCardNum) {
        this.idCardNum = idCardNum;
    }
    
    /**
     * 得到身份证详细错误信息。
     * @return 错误信息。
     */
    public String getErrMsg(){
        return this.errMsg[this.error];
    }
    
    /**
     * 是否为空。
     * @return true: null  false: not null;
     */
    public boolean isEmpty(){
        if(this.idCardNum==null)
            return true;
        else
            return this.idCardNum.trim().length()>0 ? false:true;
    }
    
    /**
     * 身份证长度。
     * @return
     */
    public int getLength(){
        return this.isEmpty() ? 0:this.idCardNum.length();
    }
    
    /**
     * 身份证长度。
     * @return
     */
    public int getLength(String str){
        return this.isEmpty() ? 0:str.length();
    }
    
    /**
     * 是否是15位身份证。
     * @return true: 15位  false：其他。
     */
    public boolean is15(){
        return this.getLength()==15;
    }
    
    /**
     * 是否是18位身份证。
     * @return true: 18位  false：其他。
     */
    public boolean is18(){
        return this.getLength()==18;
    }
    
    /**
     * 得到身份证的省份代码。
     * @return 省份代码。
     */
    public String getProvince(){
     return this.isCorrect()==0 ? this.idCardNum.substring(0,2):"";
    }
    
    /**
     * 得到身份证的城市代码。
     * @return 城市代码。
     */
    public String getCity(){
     return this.isCorrect()==0 ? this.idCardNum.substring(2,4):"";
    }
    
    /**
     * 得到身份证的区县代码。
     * @return 区县代码。
     */
    public String getCountry(){
     return this.isCorrect()==0 ? this.idCardNum.substring(4,6):"";
    }
    
    /**
     * 得到身份证的出生年份。
     * @return 出生年份。
     */
    public String getYear(){
        if(this.isCorrect()!=0)
            return "";
        
        if(this.getLength()==15){
            return "19"+this.idCardNum.substring(6,8);
        }else{
            return this.idCardNum.substring(6,10);
        }
    }
    
    /**
     * 得到身份证的出生月份。
     * @return 出生月份。
     */
    public String getMonth(){
        if(this.isCorrect()!=0)
            return "";
        
        if(this.getLength()==15){
            return this.idCardNum.substring(8,10);
        }else{
            return this.idCardNum.substring(10,12);
        }
    }
    
    /**
     * 得到身份证的出生日子。
     * @return 出生日期。
     */
    public String getDay(){
        if(this.isCorrect()!=0)
            return "";
        
        if(this.getLength()==15){
            return this.idCardNum.substring(10,12);
        }else{
            return this.idCardNum.substring(12,14);
        }
    }
    
    /**
     * 得到身份证的出生日期。
     * @return 出生日期。
     */
    public String getBirthday(){
        if(this.isCorrect()!=0)
            return "";
        
        if(this.getLength()==15){
            return "19"+this.idCardNum.substring(6,12);
        }else{
            return this.idCardNum.substring(6,14);
        }
    }
    /**
     * 得到身份证的出生年月。
     * @return 出生年月。
     */
    public String getBirthMonth(){
    		return getBirthday().substring(0, 6);
    }
    /**
     * 得到身份证的顺序号。
     * @return 顺序号。
     */
    public String getOrder(){
        if(this.isCorrect()!=0)
            return "";
        
        if(this.getLength()==15){
            return this.idCardNum.substring(12,15);
        }else{
            return this.idCardNum.substring(14,17);
        }
    }
    
    /**
     * 得到性别。
     * @return 性别：1－男  2－女
     */
    public String getSex(){
        if(this.isCorrect()!=0)
            return "";
        
        int p=Integer.parseInt(getOrder());
        if(p%2==1){
            return "男";
        }else{
            return "女";
        }
    }
    /**
     * 得到性别值。
     * @return 性别：1－男  2－女
     */
    public String getSexValue(){
        if(this.isCorrect()!=0)
            return "";
        
        int p=Integer.parseInt(getOrder());
        if(p%2==1){
            return "1";
        }else{
            return "2";
        }
    }
    
    /**
     * 得到校验位。
     * @return 校验位。
     */
    public String getCheck(){
        if(!this.isLenCorrect())
            return "";
        
        if(this.getLength()==18)
            return this.idCardNum.substring(17);
        else
            return this.getCheckBit();
    }
    
    /**
     * 得到15位身份证。
     * @return 15位身份证。 
     */
    public String to15(){
        if(this.isCorrect()!=0)
            return "";
        
        if(this.is15())
            return this.idCardNum;
        else
            return this.idCardNum.substring(0, 6)+this.idCardNum.substring(8,17);
    }
    
    /**
     * 得到18位身份证。
     * @return 18位身份证。
     */
    public String to18(){
        if(this.isCorrect()!=0)
            return "";
        
        if(this.is18())
            return this.idCardNum;
        else
            return this.idCardNum.substring(0, 6)+"19"+this.idCardNum.substring(6)+this.getCheckBit();
    }
    
    /**
     * 得到18位身份证。
     * @return 18位身份证。
     */
    public static String toNewIdCard(String tempStr){
        if(tempStr.length()==18)
            return tempStr.substring(0, 6)+tempStr.substring(8,17);
        else
            return tempStr.substring(0, 6)+"19"+tempStr.substring(6)+getCheckBit(tempStr);
    }
    
    /**
     * 校验身份证是否正确
     * @return 0：正确
     */
    public int isCorrect(){
        if(this.isEmpty()){
            this.error=IdCard.IS_EMPTY;
            return this.error; 
        }
        
        if(!this.isLenCorrect()){
            this.error=IdCard.LEN_ERROR;
            return this.error;
        }
        
        if(!this.isCharCorrect()){
            this.error=IdCard.CHAR_ERROR;
            return this.error;
        }
        
        if(!this.isDateCorrect()){
            this.error=IdCard.DATE_ERROR;
            return this.error;
        }
        
        if(this.is18()){
            if(!this.getCheck().equals(this.getCheckBit())){
                this.error=IdCard.CHECK_BIT_ERROR;
                return this.error;
            }
        }
        
        return 0;
    }
    
    
    private boolean isLenCorrect(){
        return this.is15()||this.is18();
    }
    
    /**
     * 判断身份证中出生日期是否正确。
     * @return
     */
    private boolean isDateCorrect(){
        
        /*非闰年天数*/
        int[] monthDayN={31,28,31,30,31,30,31,31,30,31,30,31};
        /*闰年天数*/
        int[] monthDayL={31,29,31,30,31,30,31,31,30,31,30,31};
        
        int month;
        if(this.is15()){
            month=Integer.parseInt(this.idCardNum.substring(8,10));
        }else{
            month=Integer.parseInt(this.idCardNum.substring(10,12));
        }
        
        int day;
        if(this.is15()){
            day=Integer.parseInt(this.idCardNum.substring(10,12));
        }else{
            day=Integer.parseInt(this.idCardNum.substring(12,14));
        }
        
        if(month>12 || month<=0){
            return false;
        }
        
        if(this.isLeapyear()){
            if(day>monthDayL[month-1] || day<=0)
                return false;
        }else{
            if(day>monthDayN[month-1] || day<=0)
                return false;
        }
        
        return true;
    }
    
    /**
     * 得到校验位。
     * @return
     */
    private String getCheckBit() {
        if(!this.isLenCorrect())
            return "";
        
        String temp = null;
        if(this.is18())
            temp=this.idCardNum;
        else
            temp=this.idCardNum.substring(0, 6)+"19"+this.idCardNum.substring(6);
        
        
        String checkTable[] = new String[] {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
        int[] wi = new int[]{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,1};
        int sum=0;
        
        for(int i=0; i<17; i++){
            String ch = temp.substring(i,i+1);
            sum = sum + Integer.parseInt(ch)*wi[i];
        }
        
        int y = sum % 11;
        
        return checkTable[y];
    }

    
    /**
     * 得到校验位。
     * @return
     */
    private static String getCheckBit(String str) {
        
        String temp = null;
        if(str.length()==18)
            temp=str;
        else
            temp=str.substring(0, 6)+"19"+str.substring(6);
        
        
        String checkTable[] = new String[] {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
        int[] wi = new int[]{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,1};
        int sum=0;
        
        for(int i=0; i<17; i++){
            String ch = temp.substring(i,i+1);
            sum = sum + Integer.parseInt(ch)*wi[i];
        }
        
        int y = sum % 11;
        
        return checkTable[y];
    }

    
    /**
     * 身份证号码中是否存在非法字符。
     * @return true: 正确  false：存在非法字符。
     */
    private boolean isCharCorrect(){
        boolean iRet=true;
        
        if(this.isLenCorrect()){
            byte[] temp = this.idCardNum.getBytes();
            
            if(this.is15()){
                for(int i=0; i<temp.length; i++){
                    if(temp[i]<48 || temp[i]>57){
                        iRet=false;
                        break;
                    }   
                }
            }
            
            if(this.is18()){
                for(int i=0; i<temp.length; i++){
                    if(temp[i]<48 || temp[i]>57){
                        if(i==17 && temp[i]!=88){
                            iRet=false;
                            break;
                        }
                    }   
                }
            }
        }else{
            iRet=false;
        }
        return iRet;
    }
    /**
     * 判断身份证的出生年份是否未闰年。
     * @return  true ：闰年  false 平年
     */
    private boolean isLeapyear(){
        String temp;
        
        if(this.is15()){
            temp="19"+this.idCardNum.substring(6,8);
        }else{
            temp=this.idCardNum.substring(6,10);
        }
        
        int year=Integer.parseInt(temp);
        
        if ((year%4 == 0 &&  year%100 != 0) || year%400 == 0)
            return true;
         else
            return false;
    }
}
